package com.lwt.monstermall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;


/**
 * 1.整合Mybatis-Plus
 *  1）、导入依赖
 *  2）、配置
 *      1、配置数据源
 *          1）、导入数据库驱动
 *          2）、在application.yml配置数据源相关信息
 *      2、配置Mybatis-Plus
 *          1）、
 *
 *
 * 2、逻辑删除
 *  1)、配置全局的逻辑删除规则
 *  2）、配置逻辑删除的组件Bean（高版本可以删除）
 *  3）、给Bean加上逻辑删除注解@TableLogic
 *
 * 3、JSR303
 *  1）、给Bean添加校验注解，并定义message提示
 *  2）、开启校验功能@Valid
 *  3）、给校验的Bean后紧跟一个BindingResult，就可以拿到校验结果
 *  4）、校验分组（多场景的复杂校验）
 *      1）、@NotBlank(message = "品牌名不能为空",groups = {AddGroup.class,UpdateGroup.class})
 *          给校验注解标注什么情况需要校验
 *      2）、@Validated({AddGroup.class})
 *      3）、默认没有指定分组的校验注解@NotBlank，在分组校验情况下不会生效，只会在不分组@Valid 或 @Validated()下生效
 *
 *
 *  5）、自动以校验
 *      1）、编写自定义校验注解
 *      2）、编写已改自定义的校验器
 *      3）、关联自定义的校验器和自定义的校验注解
 *      @Documented
 *      @Constraint(
 *         validatedBy = {ListValueConstraintValidator.class[可以指定多个不同的校验器，适配不同的类型校验]}
 *       )
 *      @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
 *      @Retention(RetentionPolicy.RUNTIME)
 *
 *
 * 4、统一的异常处理
 * @ControllerAdvice
 * 1）、编写异常处理类，使用@ControllerAdvice。
 * 2）、使用@ExceptionHandler标注方法可以处理异常
 *
 *
 * 5、模板引擎
 * 1）、thymeleaf-starter：关闭缓存
 * 2）、静态资源放在static文件夹下就可以按照路径直接访问
 * 3）、页面放在templates下，直接访问
 *  springboot，访问项目的时候，默认会找index
 * 4）、页面不重启服务器实时更新
 * 引入dev-tools
 *
 *
 * 6、整合redis
 *  1）、引入data-redist-starter
 *  2）、简单配置redis的host信息
 *  3）、使用SpringBoot自动配置好的StringRedisTemplate来操作redis
 *  redis-》map：存放数据key，数据值value
 *
 *
 *  7、整合redisson作为分布式锁等功能框架
 *  1）、引入依赖
 *  2）、配置rediss
 *
 *
 *  8.整合SpringCache简化缓存开发
 *      1）、引入依赖
 *      2）、写配置
 *          （1）、自动配置了那些？
 *              CacheAutoConfigguration会导入 RedisCacheConfiguration
 *              自动配置好缓存管理器RedisCacheManager
 *           (2)、配置redis作为缓存
*       3)、只需注解就能完成缓存操作
 *      4）、原理：
 *          CacheAutoConfigguration->RedisCacheConfiguration->
 *          自动配置RedisCacheManager->初始化所有缓存 ->每个缓存决定使用什么配置
 *          -> 如果redisCacheConfiguration有就用已有的，没有就用默认配置
 *          ->想改缓存配置，只需要给容器中放一个RedisCacheConfiguration即可
 *          ->就会应用到当前RedisCacheManager管理的缓存分区中
 *
 *      Spring-Cache的不足：
 *          1)、读模式：
 *              缓存穿透：查询一个null的数据，解决空数据：cache-null-values: true
 *              缓存击穿：大量并进来同时查询一个正好过期的的数据。解决：加锁？默认是无加锁的
 *              缓存雪崩：大量的key同时过期。解决：加随机时间，加上过期时间：time-to-live: 3600000
 *          2）、写模式
 *              1）、读写锁
 *              2）、引入Canal，感知到Mysql的更新去更新
 *              3）、读多写多直接去数据库查询就好了
 *
 *          总结：
 *          常规书记（读多写少，及时性，一致性要求不高的数据，完全可以使用springCache）
 *          特殊数据：特殊设计
 *
 *
 */

@EnableRedisHttpSession
@EnableFeignClients(basePackages = "com.lwt.monstermall.product.feign")
@MapperScan("com.lwt.monstermall.product.dao")
@SpringBootApplication
@EnableDiscoveryClient
public class MallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(MallProductApplication.class, args);
    }

}
